﻿
namespace SanguoSharp.Server
{
    public abstract class TargetPlayerCard : PlayableCard
    {
        private sealed class TargetPlayerCardResponseHandler : ResponseHandler
        {
            private TargetPlayerCard parent;
            private Card card;

            public TargetPlayerCardResponseHandler(TargetPlayerCard parent, Card card)
                : base(parent.reqType, card.Owner)
            {
                this.parent = parent;
                this.card = card;
            }
            public TargetPlayerCardResponseHandler(TargetPlayerCard parent)
                : this(parent, parent)
            {
            }

            protected override void OnRespondPlayer(Player targetPlayer)
            {
                if (targetPlayer == RequestedPlayer && !parent.includeSelf)
                    throw new BadTargetPlayerException();

                if (!targetPlayer.IsAlive)
                    throw new BadTargetPlayerException();

                if (parent.Range != 0 && parent.Range < Game.GetDistance(RequestedPlayer, targetPlayer))
                    throw new BadTargetPlayerException();

                if (card != parent)
                    Game.GameTable.PlayerPlayCard(card, parent.Type, targetPlayer);
                else
                    Game.GameTable.PlayerPlayCard(card, targetPlayer);

                if (targetPlayer.HasCardEffect(card))
                    parent.OnPlay(RequestedPlayer, targetPlayer);
                End();
            }
            protected override void OnRespondNoAction()
            {
                End();
            }
        }
        private RequestType reqType;
        private bool includeSelf;

        protected virtual int Range
        {
            get { return 0; }
        }

        protected TargetPlayerCard(Game game, int id, CardType type, CardSuit suit, CardRank rank, RequestType reqType, bool includeSelf)
            : base(game, id, type, suit, rank)
        {
            this.reqType = reqType;
            this.includeSelf = includeSelf;
        }
        protected TargetPlayerCard(Game game, int id, CardType type, CardSuit suit, CardRank rank, RequestType reqType)
            : this(game, id, type, suit, rank, reqType, false)
        {
        }

        protected override void OnPlay()
        {
            Game.GameCycle.PushTempHandler(new TargetPlayerCardResponseHandler(this));
        }
        protected override void OnPlayVirtually(Card card)
        {
            Game.GameCycle.PushTempHandler(new TargetPlayerCardResponseHandler(this, card));
        }

        protected abstract void OnPlay(Player owner, Player targetPlayer);
    }
}

